package cn.chendd.helloclient;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.TypeFilter;

import java.util.Set;

/**
 * 扫码包范围
 *
 * @author chendd
 */
public class HelloClientScan extends ClassPathBeanDefinitionScanner {

    private BeanDefinitionRegistry registry;

    public HelloClientScan(BeanDefinitionRegistry registry) {
        super(registry , false);
    }

    @Override
    public void addIncludeFilter(TypeFilter includeFilter) {
        super.addIncludeFilter(includeFilter);
    }

    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        AnnotationMetadata metadata = beanDefinition.getMetadata();
        return metadata.isInterface() && metadata.hasAnnotation(HelloClient.class.getName());
    }

    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        this.addIncludeFilter((metadataReader , metadataReaderFactory) -> true);
        Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);
        for (BeanDefinitionHolder definitionHolder : beanDefinitionHolders) {
            ScannedGenericBeanDefinition beanDefinition = (ScannedGenericBeanDefinition) definitionHolder.getBeanDefinition();
            String beanClassName = beanDefinition.getBeanClassName();
            /// 设置bean工厂构造bean时的构造方法，即此处add所传递的参数类型则表示FactoryBean构造时所调用的构造函数
            /*beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new Object[]{beanClassName , Boolean.TRUE});
            try {
                beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(Class.forName(beanClassName));
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }*/
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
            beanDefinition.setBeanClass(HelloClientFactoryBean.class);
            beanDefinition.setAutowireMode(ScannedGenericBeanDefinition.AUTOWIRE_BY_TYPE);
        }
        return beanDefinitionHolders;
    }

}
